package protocol

import (
	"encoding/binary"
	"github.com/panjf2000/gnet/v2"
	"net"
	"wths/wthsjy-im/plugins/log"
)

const (
	_fixHeadSize = 2
	_msgLenSize  = 4
)

// ReadGnet 读取io中的数据 [gnet.Conn]
func ReadGnet(r gnet.Conn) (*Packet, error) {
	// 读取协议头
	bsHeader, _ := r.Peek(_fixHeadSize)
	if len(bsHeader) < _fixHeadSize {
		return nil, ErrIncompletePacket
	}
	if _, exist := FixHeaders[MessageHeader(binary.BigEndian.Uint16(bsHeader))]; !exist {
		return nil, ErrInvalidHeader
	}

	// 读取数据体的长度
	bsDataLen, _ := r.Peek(_fixHeadSize + _msgLenSize)
	if len(bsDataLen) < _fixHeadSize+_msgLenSize {
		return nil, ErrIncompletePacket
	}
	// 真实的数据长度
	msgLen := int(binary.BigEndian.Uint32(bsDataLen[_fixHeadSize : _fixHeadSize+_msgLenSize]))

	// 读取消息体
	msg, _ := r.Peek(_fixHeadSize + _msgLenSize + msgLen)

	if len(msg) < _fixHeadSize+_msgLenSize+msgLen {
		return nil, ErrIncompletePacket
	}

	_, _ = r.Discard(_fixHeadSize + _msgLenSize + msgLen)

	tmpBs := make([]byte, len(msg))
	copy(tmpBs, msg)

	p := newPacket(MessageHeader(binary.BigEndian.Uint16(tmpBs[0:_fixHeadSize])), tmpBs[_fixHeadSize+_msgLenSize:])
	return p, nil
}

// ReadIO 读取io中的数据 [r.io.Reader]
func ReadIO(r net.Conn) (*Packet, error) {
	head := make([]byte, _fixHeadSize)
	if _, err := r.Read(head); err != nil {
		log.Error("ReadIO").Msg(err)
		return nil, err
	}

	lens := make([]byte, _msgLenSize)
	if _, err := r.Read(lens); err != nil {
		log.Error("ReadIO").Msg(err)
		return nil, err
	}
	dataSize := binary.BigEndian.Uint32(lens)
	if dataSize == 0 {
		return newPacket(MessageHeader(binary.BigEndian.Uint16(head)), nil), nil
	}
	data := make([]byte, dataSize)
	if _, err := r.Read(data); err != nil {
		log.Error("ReadIO").Msg(err)
		return nil, err
	}
	return newPacket(MessageHeader(binary.BigEndian.Uint16(head)), data), nil
}
